home *** CD-ROM | disk | FTP | other *** search
- /* WaveTableOscControl.c */
- /*****************************************************************************/
- /* */
- /* Out Of Phase: Digital Music Synthesis on General Purpose Computers */
- /* Copyright (C) 1994 Thomas R. Lawrence */
- /* */
- /* This program is free software; you can redistribute it and/or modify */
- /* it under the terms of the GNU General Public License as published by */
- /* the Free Software Foundation; either version 2 of the License, or */
- /* (at your option) any later version. */
- /* */
- /* This program is distributed in the hope that it will be useful, */
- /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
- /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
- /* GNU General Public License for more details. */
- /* */
- /* You should have received a copy of the GNU General Public License */
- /* along with this program; if not, write to the Free Software */
- /* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
- /* */
- /* Thomas R. Lawrence can be reached at tomlaw@world.std.com. */
- /* */
- /*****************************************************************************/
-
- #include "MiscInfo.h"
- #include "Audit.h"
- #include "Debug.h"
- #include "Definitions.h"
-
- #include "WaveTableOscControl.h"
- #include "FastFixedPoint.h"
- #include "Memory.h"
- #include "EnvelopeState.h"
- #include "SampleConsts.h"
- #include "LFOGenerator.h"
- #include "Multisampler.h"
- #include "OscillatorSpecifier.h"
- #include "Envelope.h"
- #include "LFOListSpecifier.h"
- #include "FastModulation.h"
- #include "64BitMath.h"
- #include "ErrorDaemon.h"
-
-
- /* prototypes for fast playback routines */
- static void Wave_Mono_8BitIn_NoTime_NoWave(WaveTableStateRec* State,
- long SampleCount, largefixedsigned* RawBuffer);
- static void Wave_Stereo_8BitIn_NoTime_NoWave(WaveTableStateRec* State,
- long SampleCount, largefixedsigned* RawBuffer);
- static void Wave_Mono_16BitIn_NoTime_NoWave(WaveTableStateRec* State,
- long SampleCount, largefixedsigned* RawBuffer);
- static void Wave_Stereo_16BitIn_NoTime_NoWave(WaveTableStateRec* State,
- long SampleCount, largefixedsigned* RawBuffer);
-
- static void Wave_Mono_8BitIn_YesTime_NoWave(WaveTableStateRec* State,
- long SampleCount, largefixedsigned* RawBuffer);
- static void Wave_Stereo_8BitIn_YesTime_NoWave(WaveTableStateRec* State,
- long SampleCount, largefixedsigned* RawBuffer);
- static void Wave_Mono_16BitIn_YesTime_NoWave(WaveTableStateRec* State,
- long SampleCount, largefixedsigned* RawBuffer);
- static void Wave_Stereo_16BitIn_YesTime_NoWave(WaveTableStateRec* State,
- long SampleCount, largefixedsigned* RawBuffer);
-
- static void Wave_Mono_8BitIn_YesTime_YesWave(WaveTableStateRec* State,
- long SampleCount, largefixedsigned* RawBuffer);
- static void Wave_Stereo_8BitIn_YesTime_YesWave(WaveTableStateRec* State,
- long SampleCount, largefixedsigned* RawBuffer);
- static void Wave_Mono_16BitIn_YesTime_YesWave(WaveTableStateRec* State,
- long SampleCount, largefixedsigned* RawBuffer);
- static void Wave_Stereo_16BitIn_YesTime_YesWave(WaveTableStateRec* State,
- long SampleCount, largefixedsigned* RawBuffer);
-
- static void Wave_NoOutput(WaveTableStateRec* State,
- long SampleCount, largefixedsigned* RawBuffer);
-
-
- /* wave table oscillator template information record */
- struct WaveTableTemplateRec
- {
- /* source information for the wave table */
- MultiSampleRec* WaveTableSourceSelector;
-
- /* sampling rate for final output */
- long FinalOutputSamplingRate;
- /* number of envelope updates per second */
- float EnvelopeTicksPerSecond;
-
- /* values for scaling the frequency of something. if we were really serious about */
- /* this, we'd traverse all of the oscillators with integral multiples or harmonic */
- /* fractions of the pitch & set their differentials to the same precision as the */
- /* worst oscillator so that they would all stay in sync as time progressed. */
- float FrequencyMultiplier;
- /* this is added after the frequency multiplier is applied */
- float FrequencyAdder;
-
- /* stereo status */
- NumChannelsType StereoPlayback;
- /* time interpolation flag */
- MyBoolean InterpolateThroughTime;
- /* inter-wave interpolation flag */
- MyBoolean InterpolateAcrossWaves;
- /* include in final output flag */
- MyBoolean IncludeInFinalOutput;
-
- /* envelope templates */
- EnvelopeRec* LoudnessEnvelopeTemplate;
- LFOListSpecRec* LoudnessLFOTemplate;
- EnvelopeRec* IndexEnvelopeTemplate;
- LFOListSpecRec* IndexLFOTemplate;
-
- /* miscellaneous control parameters */
- float StereoBias;
- float TimeDisplacement;
- float OverallOscillatorLoudness;
-
- /* error logging facility */
- ErrorDaemonRec* ErrorDaemon;
-
- /* link for list control */
- WaveTableTemplateRec* Next;
- };
-
-
- /* wave table oscillator state record */
- struct WaveTableStateRec
- {
- /* current sample position into the wave table */
- LongLongRec WaveTableSamplePosition; /* 32-bit fixed point */
- /* current increment value for the wave table sample position */
- LongLongRec WaveTableSamplePositionDifferential; /* 32-bit fixed point */
-
- /* envelope tick countdown for pre-start time */
- long PreStartCountdown;
-
- /* function for generating a bunch of samples from the wave table */
- void (*WaveTableGenSamples)(WaveTableStateRec* State,
- long SampleCount, largefixedsigned* RawBuffer);
-
- /* number of frames per table */
- long FramesPerTable;
- /* number of tables */
- long NumberOfTables;
- /* raw wave table data array */
- void** WaveTableMatrix;
- /* number of bits in the data for the table */
- NumBitsType TableNumBits;
-
- /* current index into table of waves. 0 = lowest wave table, NumberOfTables = highest */
- FastFixedType WaveTableIndex;
- /* envelope controlling wave table index */
- EvalEnvelopeRec* WaveTableIndexEnvelope;
- /* LFO generators modifying the output of the index envelope generator */
- LFOGenRec* IndexLFOGenerator;
-
- /* NOTE: either OverallLoudness or Left/RightLoudness are used, but not both */
- /* current overall loudness for oscillator */
- FastFixedType OverallLoudness; /* 15-bit fixed point, 0..1 */
- /* left channel loudness */
- FastFixedType LeftLoudness; /* 15-bit fixed point, 0..1 */
- /* right channel loudness */
- FastFixedType RightLoudness; /* 15-bit fixed point, 0..1 */
- /* panning position for splitting envelope generator into stereo channels */
- /* 0 = left channel, 0.5 = middle, 1 = right channel */
- FastFixedType Panning; /* 15-bit fixed point, -1..1 */
- /* envelope that is generating the loudness information */
- EvalEnvelopeRec* WaveTableLoudnessEnvelope;
- /* LFO generators modifying the output of the loudness envelope generator */
- LFOGenRec* LoudnessLFOGenerator;
-
- /* this flag is True if the wave table data was defined at the specified pitch */
- /* (and the wave table array is thus valid) or False if there is no wave table */
- /* at this pitch (and the array is invalid) */
- MyBoolean WaveTableWasDefined;
-
- /* this field contains the overall volume scaling for everything so that we */
- /* can treat the envelopes as always going between 0 and 1. */
- float NoteLoudnessScaling;
-
- /* static information for the wave table */
- WaveTableTemplateRec Template; /* a copy of the data */
-
- /* link for list control */
- WaveTableStateRec* Next;
- };
-
-
-
-
- static WaveTableTemplateRec* WaveTableTemplateFreeList = NIL;
- static WaveTableStateRec* WaveTableStateFreeList = NIL;
-
-
- /* get rid of all cached memory for state or template records */
- void FlushWaveTableOscControl(void)
- {
- while (WaveTableTemplateFreeList != NIL)
- {
- WaveTableTemplateRec* Temp;
-
- Temp = WaveTableTemplateFreeList;
- WaveTableTemplateFreeList = WaveTableTemplateFreeList->Next;
- ReleasePtr((char*)Temp);
- }
-
- while (WaveTableStateFreeList != NIL)
- {
- WaveTableStateRec* Temp;
-
- Temp = WaveTableStateFreeList;
- WaveTableStateFreeList = WaveTableStateFreeList->Next;
- ReleasePtr((char*)Temp);
- }
- }
-
-
- #if DEBUG
- static void CheckValidWaveTableTemplate(WaveTableTemplateRec* Object)
- {
- WaveTableTemplateRec* Scan;
-
- Scan = WaveTableTemplateFreeList;
- while (Scan != NIL)
- {
- if (Scan == Object)
- {
- PRERR(ForceAbort,"CheckValidWaveTableTemplate: template is on free list");
- }
- Scan = Scan->Next;
- }
- }
- #else
- #define CheckValidWaveTableTemplate(x) ((void)0)
- #endif
-
-
- #if DEBUG
- static void CheckValidWaveTableState(WaveTableStateRec* Object)
- {
- WaveTableStateRec* Scan;
-
- Scan = WaveTableStateFreeList;
- while (Scan != NIL)
- {
- if (Scan == Object)
- {
- PRERR(ForceAbort,"CheckValidWaveTableState: state is on free list");
- }
- Scan = Scan->Next;
- }
- }
- #else
- #define CheckValidWaveTableState(x) ((void)0)
- #endif
-
-
- /* perform one envelope update cycle */
- void UpdateWaveTableEnvelopes(WaveTableStateRec* State)
- {
- FastFixedType Temp;
-
- CheckPtrExistence(State);
- CheckValidWaveTableState(State);
-
- /* this is for the benefit of resampling only -- envelope generators do their */
- /* own pre-origin sequencing */
- if (State->PreStartCountdown > 0)
- {
- State->PreStartCountdown -= 1;
- }
-
- Temp = (State->NumberOfTables - 1) * LFOGenUpdateCycle(State->IndexLFOGenerator,
- EnvelopeUpdate(State->WaveTableIndexEnvelope));
- if (Temp < 0)
- {
- Temp = 0;
- }
- else if (Temp > Int2FastFixed(State->NumberOfTables - 1))
- {
- Temp = Int2FastFixed(State->NumberOfTables - 1);
- }
- State->WaveTableIndex = Temp;
-
- Temp = State->NoteLoudnessScaling * LFOGenUpdateCycle(State->LoudnessLFOGenerator,
- EnvelopeUpdate(State->WaveTableLoudnessEnvelope));
- /* fast fixed has a very narrow range, so overflow can't be permitted: */
- /* 15x15->30 bits, with 2 extra bits; we use one for sign and the other */
- /* to permit the representation of 1 and -1. */
- if (State->Template.StereoPlayback == eSampleMono)
- {
- if (Temp < - Int2FastFixed(1))
- {
- ErrorDaemonReportClamping(State->Template.ErrorDaemon,
- - FastFixed2Float(Temp));
- Temp = - Int2FastFixed(1);
- }
- else if (Temp > Int2FastFixed(1))
- {
- ErrorDaemonReportClamping(State->Template.ErrorDaemon,
- FastFixed2Float(Temp));
- Temp = Int2FastFixed(1);
- }
- State->OverallLoudness = Temp;
- }
- else
- {
- FastFixedType LeftVolumeScaling;
- FastFixedType RightVolumeScaling;
- FastFixedType MaxVolScaling;
- FastFixedType MaxTemp;
-
- LeftVolumeScaling = FastFixedTimesFastFixedToFastFixed(Double2FastFixed(0.5),
- Int2FastFixed(1) - State->Panning);
- RightVolumeScaling = FastFixedTimesFastFixedToFastFixed(Double2FastFixed(0.5),
- Int2FastFixed(1) + State->Panning);
-
- if (((LeftVolumeScaling >= 0) ? LeftVolumeScaling : (- LeftVolumeScaling))
- > ((RightVolumeScaling >= 0) ? RightVolumeScaling : (- RightVolumeScaling)))
- {
- MaxVolScaling = ((LeftVolumeScaling >= 0)
- ? LeftVolumeScaling : (- LeftVolumeScaling));
- }
- else
- {
- MaxVolScaling = ((RightVolumeScaling >= 0)
- ? RightVolumeScaling : (- RightVolumeScaling));
- }
- MaxTemp = Double2FastFixed((float)1 / FastFixed2Float(MaxVolScaling));
- if (Temp < - MaxTemp)
- {
- ErrorDaemonReportClamping(State->Template.ErrorDaemon,
- - FastFixed2Float(Temp) / FastFixed2Float(MaxTemp));
- Temp = - MaxTemp;
- }
- else if (Temp > MaxTemp)
- {
- ErrorDaemonReportClamping(State->Template.ErrorDaemon,
- FastFixed2Float(Temp) / FastFixed2Float(MaxTemp));
- Temp = MaxTemp;
- }
-
- State->LeftLoudness = FastFixedTimesFastFixedToFastFixed(
- LeftVolumeScaling,Temp);
- State->RightLoudness = FastFixedTimesFastFixedToFastFixed(
- RightVolumeScaling,Temp);
- }
- }
-
-
- /* dispose of the wave table state record */
- void DisposeWaveTableState(WaveTableStateRec* State)
- {
- CheckPtrExistence(State);
- CheckValidWaveTableState(State);
-
- DisposeEnvelopeStateRecord(State->WaveTableIndexEnvelope);
- DisposeLFOGenerator(State->IndexLFOGenerator);
- DisposeEnvelopeStateRecord(State->WaveTableLoudnessEnvelope);
- DisposeLFOGenerator(State->LoudnessLFOGenerator);
-
- State->Next = WaveTableStateFreeList;
- WaveTableStateFreeList = State;
- }
-
-
- /* dispose of the wave table information template */
- void DisposeWaveTableTemplate(WaveTableTemplateRec* Template)
- {
- CheckPtrExistence(Template);
- CheckValidWaveTableTemplate(Template);
-
- DisposeMultisample(Template->WaveTableSourceSelector);
-
- Template->Next = WaveTableTemplateFreeList;
- WaveTableTemplateFreeList = Template;
- }
-
-
- /* create a new wave table template */
- WaveTableTemplateRec* NewWaveTableTemplate(struct OscillatorRec* Oscillator,
- float EnvelopeTicksPerSecond, long SamplingRate,
- MyBoolean Stereo, MyBoolean TimeInterp, MyBoolean WaveInterp,
- ErrorDaemonRec* ErrorDaemon)
- {
- WaveTableTemplateRec* Template;
-
- CheckPtrExistence(ErrorDaemon);
- CheckPtrExistence(Oscillator);
- ERROR(OscillatorGetWhatKindItIs(Oscillator) != eOscillatorWaveTable,PRERR(ForceAbort,
- "NewWaveTableTemplate: oscillator is not a wave table"));
-
- if (WaveTableTemplateFreeList != NIL)
- {
- Template = WaveTableTemplateFreeList;
- WaveTableTemplateFreeList = WaveTableTemplateFreeList->Next;
- }
- else
- {
- Template = (WaveTableTemplateRec*)AllocPtrCanFail(sizeof(WaveTableTemplateRec),
- "WaveTableTemplateRec");
- if (Template == NIL)
- {
- return NIL;
- }
- }
- EXECUTE(Template->Next = (WaveTableTemplateRec*)0x81818181;)
-
- Template->WaveTableSourceSelector = NewMultisampleWaveTable(
- OscillatorGetSampleIntervalList(Oscillator));
- if (Template->WaveTableSourceSelector == NIL)
- {
- FailurePoint1:
- Template->Next = WaveTableTemplateFreeList;
- WaveTableTemplateFreeList = Template;
- return NIL;
- }
-
- Template->FinalOutputSamplingRate = SamplingRate;
- Template->EnvelopeTicksPerSecond = EnvelopeTicksPerSecond;
- Template->OverallOscillatorLoudness = OscillatorGetOutputLoudness(Oscillator);
-
- /* it might be better to handle divisor and multiplier separately -- we would */
- /* want to do that if we were trying to guarantee that all harmonic */
- /* oscillators ran in lock-step */
- Template->FrequencyMultiplier = OscillatorGetFrequencyMultiplier(Oscillator)
- / OscillatorGetFrequencyDivisor(Oscillator);
- Template->FrequencyAdder = OscillatorGetFrequencyAdder(Oscillator);
-
- Template->StereoBias = OscillatorGetStereoBias(Oscillator);
- Template->TimeDisplacement = OscillatorGetTimeDisplacement(Oscillator);
-
- if (Stereo)
- {
- Template->StereoPlayback = eSampleStereo;
- }
- else
- {
- Template->StereoPlayback = eSampleMono;
- }
- Template->InterpolateThroughTime = TimeInterp;
- Template->InterpolateAcrossWaves = WaveInterp;
- Template->IncludeInFinalOutput = IncludeOscillatorInFinalOutput(Oscillator);
-
- /* these are just references */
- Template->LoudnessEnvelopeTemplate = OscillatorGetLoudnessEnvelope(Oscillator);
- Template->LoudnessLFOTemplate = OscillatorGetLoudnessLFOList(Oscillator);
- Template->IndexEnvelopeTemplate = OscillatorGetExcitationEnvelope(Oscillator);
- Template->IndexLFOTemplate = OscillatorGetExcitationLFOList(Oscillator);
-
- /* another reference */
- Template->ErrorDaemon = ErrorDaemon;
-
- return Template;
- }
-
-
- /* create a new wave table state object. */
- WaveTableStateRec* NewWaveTableState(WaveTableTemplateRec* Template,
- float FreqForMultisampling, float Accent1, float Accent2,
- float Accent3, float Accent4, float Loudness, float HurryUp,
- long* PreOriginTimeOut, float StereoPosition,
- float InitialFrequency)
- {
- WaveTableStateRec* State;
- long MaxPreOrigin;
- long OnePreOrigin;
-
- CheckPtrExistence(Template);
- CheckValidWaveTableTemplate(Template);
-
- if (WaveTableStateFreeList != NIL)
- {
- State = WaveTableStateFreeList;
- WaveTableStateFreeList = WaveTableStateFreeList->Next;
- }
- else
- {
- State = (WaveTableStateRec*)AllocPtrCanFail(sizeof(WaveTableStateRec),
- "WaveTableStateRec");
- if (State == NIL)
- {
- FailurePoint1:
- return NIL;
- }
- }
- EXECUTE(State->Next = (WaveTableStateRec*)0x81818181;)
-
- State->Template = *Template;
-
- MaxPreOrigin = 0;
-
- Double2LongLong(0,State->WaveTableSamplePosition);
- /* State->WaveTableSamplePositionDifferential specified in separate call */
-
- State->NoteLoudnessScaling = Loudness * Template->OverallOscillatorLoudness;
-
- State->WaveTableWasDefined = GetMultisampleReferenceWaveTable(
- Template->WaveTableSourceSelector,FreqForMultisampling,&(State->WaveTableMatrix),
- &(State->FramesPerTable),&(State->NumberOfTables),&(State->TableNumBits));
-
- /* Template->IncludeInFinalOutput: */
- /* the routine pointer is not used for modulation */
- /* State->WaveTableWasDefined: */
- /* if there is no wave table defined for the current pitch, then we don't */
- /* bother generating any data */
- /* State->FramesPerTable > 0: */
- /* if the wave table is empty, then we don't do any work (and we must not, */
- /* since array accesses would cause a crash) */
- if (Template->IncludeInFinalOutput && State->WaveTableWasDefined
- && (State->FramesPerTable > 0))
- {
- if (Template->StereoPlayback == eSampleStereo)
- {
- if (State->TableNumBits == eSample16bit)
- {
- if (Template->InterpolateAcrossWaves)
- {
- State->WaveTableGenSamples = &Wave_Stereo_16BitIn_YesTime_YesWave;
- }
- else if (Template->InterpolateThroughTime)
- {
- State->WaveTableGenSamples = &Wave_Stereo_16BitIn_YesTime_NoWave;
- }
- else
- {
- State->WaveTableGenSamples = &Wave_Stereo_16BitIn_NoTime_NoWave;
- }
- }
- else
- {
- if (Template->InterpolateAcrossWaves)
- {
- State->WaveTableGenSamples = &Wave_Stereo_8BitIn_YesTime_YesWave;
- }
- else if (Template->InterpolateThroughTime)
- {
- State->WaveTableGenSamples = &Wave_Stereo_8BitIn_YesTime_NoWave;
- }
- else
- {
- State->WaveTableGenSamples = &Wave_Stereo_8BitIn_NoTime_NoWave;
- }
- }
- }
- else
- {
- if (State->TableNumBits == eSample16bit)
- {
- if (Template->InterpolateAcrossWaves)
- {
- State->WaveTableGenSamples = &Wave_Mono_16BitIn_YesTime_YesWave;
- }
- else if (Template->InterpolateThroughTime)
- {
- State->WaveTableGenSamples = &Wave_Mono_16BitIn_YesTime_NoWave;
- }
- else
- {
- State->WaveTableGenSamples = &Wave_Mono_16BitIn_NoTime_NoWave;
- }
- }
- else
- {
- if (Template->InterpolateAcrossWaves)
- {
- State->WaveTableGenSamples = &Wave_Mono_8BitIn_YesTime_YesWave;
- }
- else if (Template->InterpolateThroughTime)
- {
- State->WaveTableGenSamples = &Wave_Mono_8BitIn_YesTime_NoWave;
- }
- else
- {
- State->WaveTableGenSamples = &Wave_Mono_8BitIn_NoTime_NoWave;
- }
- }
- }
- }
- else
- {
- State->WaveTableGenSamples = &Wave_NoOutput;
- }
-
- State->PreStartCountdown = Template->TimeDisplacement
- * Template->EnvelopeTicksPerSecond + 0.5;
- if (- State->PreStartCountdown > MaxPreOrigin)
- {
- MaxPreOrigin = - State->PreStartCountdown;
- }
-
- /* State->WaveTableIndex determined by envelope update */
- State->WaveTableIndexEnvelope = NewEnvelopeStateRecord(
- Template->IndexEnvelopeTemplate,Accent1,Accent2,Accent3,Accent4,InitialFrequency,
- 1,HurryUp,Template->EnvelopeTicksPerSecond,&OnePreOrigin);
- if (State->WaveTableIndexEnvelope == NIL)
- {
- FailurePoint2:
- State->Next = WaveTableStateFreeList;
- WaveTableStateFreeList = State;
- goto FailurePoint1;
- }
- if (OnePreOrigin > MaxPreOrigin)
- {
- MaxPreOrigin = OnePreOrigin;
- }
- State->IndexLFOGenerator = NewLFOGenerator(Template->IndexLFOTemplate,
- &OnePreOrigin,Accent1,Accent2,Accent3,Accent4,InitialFrequency,HurryUp,
- Template->EnvelopeTicksPerSecond,1,1,eLFOArithDefault,FreqForMultisampling);
- if (State->IndexLFOGenerator == NIL)
- {
- FailurePoint3:
- DisposeEnvelopeStateRecord(State->WaveTableIndexEnvelope);
- goto FailurePoint2;
- }
- if (OnePreOrigin > MaxPreOrigin)
- {
- MaxPreOrigin = OnePreOrigin;
- }
-
- /* State->OverallLoudness, State->LeftLoudness, State->RightLoudness */
- /* are determined by the envelope update */
- StereoPosition += Template->StereoBias;
- if (StereoPosition < -1)
- {
- StereoPosition = -1;
- }
- else if (StereoPosition > 1)
- {
- StereoPosition = 1;
- }
- State->Panning = Double2FastFixed(StereoPosition);
- State->WaveTableLoudnessEnvelope = NewEnvelopeStateRecord(
- Template->LoudnessEnvelopeTemplate,Accent1,Accent2,Accent3,Accent4,
- InitialFrequency,1,HurryUp,Template->EnvelopeTicksPerSecond,&OnePreOrigin);
- if (State->WaveTableLoudnessEnvelope == NIL)
- {
- FailurePoint4:
- DisposeLFOGenerator(State->IndexLFOGenerator);
- goto FailurePoint3;
- }
- if (OnePreOrigin > MaxPreOrigin)
- {
- MaxPreOrigin = OnePreOrigin;
- }
- State->LoudnessLFOGenerator = NewLFOGenerator(Template->LoudnessLFOTemplate,
- &OnePreOrigin,Accent1,Accent2,Accent3,Accent4,InitialFrequency,HurryUp,
- Template->EnvelopeTicksPerSecond,1,1,eLFOArithDefault,FreqForMultisampling);
- if (State->LoudnessLFOGenerator == NIL)
- {
- FailurePoint5:
- DisposeEnvelopeStateRecord(State->WaveTableLoudnessEnvelope);
- goto FailurePoint4;
- }
- if (OnePreOrigin > MaxPreOrigin)
- {
- MaxPreOrigin = OnePreOrigin;
- }
-
- *PreOriginTimeOut = MaxPreOrigin;
- return State;
- }
-
-
- /* fix up pre-origin time for the wave table state object */
- void FixUpWaveTableStatePreOrigin(WaveTableStateRec* State,
- long ActualPreOrigin)
- {
- CheckPtrExistence(State);
- CheckValidWaveTableState(State);
-
- EnvelopeStateFixUpInitialDelay(State->WaveTableIndexEnvelope,ActualPreOrigin);
- EnvelopeStateFixUpInitialDelay(State->WaveTableLoudnessEnvelope,ActualPreOrigin);
- LFOGeneratorFixEnvelopeOrigins(State->IndexLFOGenerator,ActualPreOrigin);
- LFOGeneratorFixEnvelopeOrigins(State->LoudnessLFOGenerator,ActualPreOrigin);
-
- State->PreStartCountdown += ActualPreOrigin;
- }
-
-
- /* set a new frequency for a wave table state object. used for portamento */
- /* and modulation of frequency (vibrato) */
- void WaveTableStateNewFrequency(WaveTableStateRec* State,
- float NewFrequencyHertz)
- {
- CheckPtrExistence(State);
- CheckValidWaveTableState(State);
-
- Double2LongLong((NewFrequencyHertz * State->Template.FrequencyMultiplier
- + State->Template.FrequencyAdder) / State->Template.FinalOutputSamplingRate
- * State->FramesPerTable,State->WaveTableSamplePositionDifferential);
- }
-
-
- /* send a key-up signal to one of the oscillators */
- void WaveTableKeyUpSustain1(WaveTableStateRec* State)
- {
- CheckPtrExistence(State);
- CheckValidWaveTableState(State);
- LFOGeneratorKeyUpSustain1(State->IndexLFOGenerator);
- LFOGeneratorKeyUpSustain1(State->LoudnessLFOGenerator);
- EnvelopeKeyUpSustain1(State->WaveTableIndexEnvelope);
- EnvelopeKeyUpSustain1(State->WaveTableLoudnessEnvelope);
- }
-
-
- /* send a key-up signal to one of the oscillators */
- void WaveTableKeyUpSustain2(WaveTableStateRec* State)
- {
- CheckPtrExistence(State);
- CheckValidWaveTableState(State);
- LFOGeneratorKeyUpSustain2(State->IndexLFOGenerator);
- LFOGeneratorKeyUpSustain2(State->LoudnessLFOGenerator);
- EnvelopeKeyUpSustain2(State->WaveTableIndexEnvelope);
- EnvelopeKeyUpSustain2(State->WaveTableLoudnessEnvelope);
- }
-
-
- /* send a key-up signal to one of the oscillators */
- void WaveTableKeyUpSustain3(WaveTableStateRec* State)
- {
- CheckPtrExistence(State);
- CheckValidWaveTableState(State);
- LFOGeneratorKeyUpSustain3(State->IndexLFOGenerator);
- LFOGeneratorKeyUpSustain3(State->LoudnessLFOGenerator);
- EnvelopeKeyUpSustain3(State->WaveTableIndexEnvelope);
- EnvelopeKeyUpSustain3(State->WaveTableLoudnessEnvelope);
- }
-
-
- /* restart a wave table oscillator. this is used for tie continuations */
- void RestartWaveTableState(WaveTableStateRec* State,
- float NewFreqMultisampling, float NewAccent1, float NewAccent2,
- float NewAccent3, float NewAccent4, float NewLoudness,
- float NewHurryUp, MyBoolean RetriggerEnvelopes,
- float NewStereoPosition, float NewInitialFrequency)
- {
- CheckPtrExistence(State);
- CheckValidWaveTableState(State);
-
- NewStereoPosition += State->Template.StereoBias;
- if (NewStereoPosition < -1)
- {
- NewStereoPosition = -1;
- }
- else if (NewStereoPosition > 1)
- {
- NewStereoPosition = 1;
- }
- State->Panning = Double2FastFixed(NewStereoPosition);
-
- State->NoteLoudnessScaling = NewLoudness * State->Template.OverallOscillatorLoudness;
-
- EnvelopeRetriggerFromOrigin(State->WaveTableIndexEnvelope,NewAccent1,NewAccent2,
- NewAccent3,NewAccent4,NewInitialFrequency,1,NewHurryUp,
- State->Template.EnvelopeTicksPerSecond,RetriggerEnvelopes);
- EnvelopeRetriggerFromOrigin(State->WaveTableLoudnessEnvelope,NewAccent1,
- NewAccent2,NewAccent3,NewAccent4,NewInitialFrequency,1,NewHurryUp,
- State->Template.EnvelopeTicksPerSecond,RetriggerEnvelopes);
- LFOGeneratorRetriggerFromOrigin(State->IndexLFOGenerator,NewAccent1,NewAccent2,
- NewAccent3,NewAccent4,NewInitialFrequency,NewHurryUp,
- State->Template.EnvelopeTicksPerSecond,1,1,RetriggerEnvelopes);
- LFOGeneratorRetriggerFromOrigin(State->LoudnessLFOGenerator,NewAccent1,
- NewAccent2,NewAccent3,NewAccent4,NewInitialFrequency,NewHurryUp,
- State->Template.EnvelopeTicksPerSecond,1,1,RetriggerEnvelopes);
- }
-
-
- /* generate one sequence of samples */
- void WaveTableGenSamples(WaveTableStateRec* State,
- long SampleCount, largefixedsigned* RawBuffer)
- {
- CheckPtrExistence(State);
- CheckValidWaveTableState(State);
-
- if (State->PreStartCountdown <= 0)
- {
- (*State->WaveTableGenSamples)(State,SampleCount,RawBuffer);
- }
- }
-
-
- /* find out if the wave table oscillator has finished */
- MyBoolean WaveTableIsItFinished(WaveTableStateRec* State)
- {
- CheckPtrExistence(State);
- CheckValidWaveTableState(State);
-
- /* we are finished when one of the following conditions is met: */
- /* - output volume is zero AND loudness envelope is finished */
- /* - we are not generating any signal */
- if (!State->WaveTableWasDefined)
- {
- return True;
- }
- if (IsEnvelopeAtEnd(State->WaveTableLoudnessEnvelope))
- {
- if (State->Template.StereoPlayback == eSampleStereo)
- {
- if ((State->LeftLoudness == 0) && (State->RightLoudness == 0))
- {
- return True;
- }
- }
- else
- {
- if (State->OverallLoudness == 0)
- {
- return True;
- }
- }
- }
- return IsEnvelopeAtEnd(State->WaveTableLoudnessEnvelope);
- }
-
-
- /* generate a single sample (called for modulation chains) */
- /* OutputPlace should have 1 entry for mono output or 2 entries for stereo output */
- float WaveTableGenOneSample(WaveTableStateRec* State,
- ModulationTypes* PhaseGenModulateHow,
- float* PhaseGenModulationScaling,
- float* PhaseGenModulationOrigin,
- float* PhaseGenOldValues,
- long* PhaseGenIndirectionTable,
- long NumberOfPhaseGenModulators,
- ModulationTypes* OutputModulateHow,
- float* OutputModulationScaling,
- float* OutputModulationOrigin,
- float* OutputOldValues,
- long* OutputIndirectionTable,
- long NumberOfOutputModulators,
- largefixedsigned* OutputPlace)
- {
- float ReturnValue;
- LongLongRec FrameIndex;
- signed long Final; /* both 16-bit int & largefixedsigned */
-
- CheckPtrExistence(State);
- CheckValidWaveTableState(State);
-
- /* should we bother doing any work? */
- if (!State->WaveTableWasDefined || (State->FramesPerTable == 0)
- || (State->PreStartCountdown > 0))
- {
- /* modulate against zero */
- if (State->Template.StereoPlayback == eSampleStereo)
- {
- OutputPlace[0] += double2largefixed(ApplyModulation(0,OutputModulateHow,
- OutputModulationScaling,OutputModulationOrigin,OutputOldValues,
- OutputIndirectionTable,NumberOfOutputModulators));
- OutputPlace[1] += double2largefixed(ApplyModulation(0,OutputModulateHow,
- OutputModulationScaling,OutputModulationOrigin,OutputOldValues,
- OutputIndirectionTable,NumberOfOutputModulators));
- }
- else
- {
- OutputPlace[0] += double2largefixed(ApplyModulation(0,OutputModulateHow,
- OutputModulationScaling,OutputModulationOrigin,OutputOldValues,
- OutputIndirectionTable,NumberOfOutputModulators));
- }
- return 0;
- }
-
- /* generate the sample position */
- /* we want the modulation to be the same no matter how large the wavetable */
- /* is, so we need to normalize the wave table index. */
- Double2LongLong(ApplyModulation(LongLong2Double(State->WaveTableSamplePosition)
- / State->FramesPerTable,PhaseGenModulateHow,PhaseGenModulationScaling,
- PhaseGenModulationOrigin,PhaseGenOldValues,PhaseGenIndirectionTable,
- NumberOfPhaseGenModulators) * State->FramesPerTable,FrameIndex);
-
- ERROR((State->WaveTableIndex < 0) || (State->WaveTableIndex
- > Int2FastFixed(State->NumberOfTables - 1)),PRERR(ForceAbort,
- "WaveTableGenOneSample: wave index out of range"));
-
- /* big selector of the thing to do */
- if (State->Template.InterpolateAcrossWaves)
- {
- /* wave & time interp */
- /* do the stuff for one wave table */
- if (State->TableNumBits == eSample16bit)
- {
- /* 16-bit sampling, wave interp, time interp */
-
- signed short* WaveData0;
- signed short* WaveData1;
- FastFixedType Wave0Weight;
-
- FastFixedType LeftWeight;
- long ArraySubscript;
- signed long Left0Value;
- signed long Right0Value;
- signed long Left1Value;
- signed long Right1Value;
- FastFixedType Wave0Temp;
-
- if (FastFixed2Int(State->WaveTableIndex) == State->NumberOfTables - 1)
- {
- /* this is done in case the wave table index is at the maximum, */
- /* in which case there is no table+1 to interpolate with. */
- goto W16BitTimeNoWave;
- }
- PRNGCHK(State->WaveTableMatrix,&(State->WaveTableMatrix[FastFixed2Int(
- State->WaveTableIndex)]),sizeof(State->WaveTableMatrix[FastFixed2Int(
- State->WaveTableIndex)]));
- WaveData0 = (signed short*)(State->WaveTableMatrix[
- FastFixed2Int(State->WaveTableIndex)]);
- PRNGCHK(State->WaveTableMatrix,&(State->WaveTableMatrix[FastFixed2Int(
- State->WaveTableIndex) + 1]),sizeof(State->WaveTableMatrix[FastFixed2Int(
- State->WaveTableIndex) + 1]));
- WaveData1 = (signed short*)(State->WaveTableMatrix[
- FastFixed2Int(State->WaveTableIndex) + 1]);
- Wave0Weight = State->WaveTableIndex & FASTFIXEDFRACTMASK;
-
- LeftWeight = LongLongLowHalf(FrameIndex) >> (32 - FASTFIXEDPRECISION);
- ArraySubscript = LongLongHighHalf(FrameIndex) & (State->FramesPerTable - 1);
- /* L+F(R-L) -- applied twice */
- Left0Value = WaveData0[ArraySubscript];
- Right0Value = WaveData0[ArraySubscript + 1];
- Left1Value = WaveData1[ArraySubscript];
- Right1Value = WaveData1[ArraySubscript + 1];
- Wave0Temp = Left0Value + ((LeftWeight * (Right0Value - Left0Value)) >> 15);
- Final = Wave0Temp + ((Wave0Weight * (Left1Value + ((LeftWeight
- * (Right1Value - Left1Value)) >> 15)) - Wave0Temp) >> 15);
- }
- else
- {
- /* 8-bit sampling, wave interp, time interp */
-
- signed char* WaveData0;
- signed char* WaveData1;
- FastFixedType Wave0Weight;
-
- FastFixedType LeftWeight;
- long ArraySubscript;
- signed long Left0Value;
- signed long Right0Value;
- signed long Left1Value;
- signed long Right1Value;
- FastFixedType Wave0Temp;
-
- if (FastFixed2Int(State->WaveTableIndex) == State->NumberOfTables - 1)
- {
- /* this is done in case the wave table index is at the maximum, */
- /* in which case there is no table+1 to interpolate with. */
- goto W8BitTimeNoWave;
- }
- PRNGCHK(State->WaveTableMatrix,&(State->WaveTableMatrix[FastFixed2Int(
- State->WaveTableIndex)]),sizeof(State->WaveTableMatrix[FastFixed2Int(
- State->WaveTableIndex)]));
- WaveData0 = (signed char*)(State->WaveTableMatrix[
- FastFixed2Int(State->WaveTableIndex)]);
- PRNGCHK(State->WaveTableMatrix,&(State->WaveTableMatrix[FastFixed2Int(
- State->WaveTableIndex) + 1]),sizeof(State->WaveTableMatrix[FastFixed2Int(
- State->WaveTableIndex) + 1]));
- WaveData1 = (signed char*)(State->WaveTableMatrix[
- FastFixed2Int(State->WaveTableIndex) + 1]);
- Wave0Weight = State->WaveTableIndex & FASTFIXEDFRACTMASK;
-
- LeftWeight = LongLongLowHalf(FrameIndex) >> (32 - FASTFIXEDPRECISION);
- ArraySubscript = LongLongHighHalf(FrameIndex) & (State->FramesPerTable - 1);
- /* L+F(R-L) -- applied twice */
- Left0Value = ((signed long)WaveData0[ArraySubscript]) << 8; /* convert to 16-bit */
- Right0Value = ((signed long)WaveData0[ArraySubscript + 1]) << 8; /* to 16-bit */
- Left1Value = ((signed long)WaveData1[ArraySubscript]) << 8; /* convert to 16-bit */
- Right1Value = ((signed long)WaveData1[ArraySubscript + 1]) << 8; /* to 16-bit */
- Wave0Temp = Left0Value + ((LeftWeight * (Right0Value - Left0Value)) >> 15);
- Final = Wave0Temp + ((Wave0Weight * (Left1Value + ((LeftWeight
- * (Right1Value - Left1Value)) >> 15) - Wave0Temp)) >> 15);
- }
- }
- else if (State->Template.InterpolateThroughTime)
- {
- /* time interp */
- /* do the stuff for one wave table */
- if (State->TableNumBits == eSample16bit)
- {
- /* 16-bit sampling, time interp */
-
- signed short* WaveData;
-
- FastFixedType LeftWeight;
- long ArraySubscript;
- signed long LeftValue;
- signed long RightValue;
-
- W16BitTimeNoWave:
-
- PRNGCHK(State->WaveTableMatrix,&(State->WaveTableMatrix[FastFixed2Int(
- State->WaveTableIndex)]),sizeof(State->WaveTableMatrix[FastFixed2Int(
- State->WaveTableIndex)]));
- WaveData = (signed short*)(State->WaveTableMatrix[
- FastFixed2Int(State->WaveTableIndex)]);
-
- LeftWeight = LongLongLowHalf(FrameIndex) >> (32 - FASTFIXEDPRECISION);
- ArraySubscript = LongLongHighHalf(FrameIndex) & (State->FramesPerTable - 1);
- /* L+F(R-L) */
- LeftValue = WaveData[ArraySubscript];
- RightValue = WaveData[ArraySubscript + 1];
- Final = LeftValue + ((LeftWeight * (RightValue - LeftValue)) >> 15);
- }
- else
- {
- /* 8-bit sampling, time interp */
-
- signed char* WaveData;
-
- FastFixedType LeftWeight;
- long ArraySubscript;
- signed long LeftValue;
- signed long RightValue;
-
- W8BitTimeNoWave:
-
- PRNGCHK(State->WaveTableMatrix,&(State->WaveTableMatrix[FastFixed2Int(
- State->WaveTableIndex)]),sizeof(State->WaveTableMatrix[FastFixed2Int(
- State->WaveTableIndex)]));
- WaveData = (signed char*)(State->WaveTableMatrix[
- FastFixed2Int(State->WaveTableIndex)]);
-
- LeftWeight = LongLongLowHalf(FrameIndex) >> (32 - FASTFIXEDPRECISION);
- ArraySubscript = LongLongHighHalf(FrameIndex) & (State->FramesPerTable - 1);
- /* L+F(R-L) */
- LeftValue = ((signed long)WaveData[ArraySubscript]) << 8; /* convert to 16-bit */
- RightValue = ((signed long)WaveData[ArraySubscript + 1]) << 8; /* to 16-bit */
- Final = LeftValue + ((LeftWeight * (RightValue - LeftValue)) >> 15);
- }
- }
- else
- {
- /* no interp */
- /* do the stuff for one wave table */
- if (State->TableNumBits == eSample16bit)
- {
- /* 16-bit sampling */
-
- signed short* WaveData;
-
- PRNGCHK(State->WaveTableMatrix,&(State->WaveTableMatrix[FastFixed2Int(
- State->WaveTableIndex)]),sizeof(State->WaveTableMatrix[FastFixed2Int(
- State->WaveTableIndex)]));
- WaveData = (signed short*)(State->WaveTableMatrix[
- FastFixed2Int(State->WaveTableIndex)]);
-
- Final = WaveData[LongLongHighHalf(FrameIndex) & (State->FramesPerTable - 1)];
- }
- else
- {
- /* 8-bit sampling */
-
- signed char* WaveData;
-
- PRNGCHK(State->WaveTableMatrix,&(State->WaveTableMatrix[FastFixed2Int(
- State->WaveTableIndex)]),sizeof(State->WaveTableMatrix[FastFixed2Int(
- State->WaveTableIndex)]));
- WaveData = (signed char*)(State->WaveTableMatrix[
- FastFixed2Int(State->WaveTableIndex)]);
-
- Final = WaveData[LongLongHighHalf(FrameIndex) & (State->FramesPerTable - 1)];
- }
- }
-
- if (State->Template.StereoPlayback == eSampleStereo)
- {
- ReturnValue = ((float)Final / MAX16BIT) * ((FastFixed2Float(
- State->LeftLoudness) + FastFixed2Float(State->RightLoudness)) / 2);
- if (State->Template.IncludeInFinalOutput)
- {
- OutputPlace[0] += double2largefixed(ApplyModulation(largefixed2single(
- FastFixedTimes16BitTo24Bit((signed long)(State->LeftLoudness
- * State->NoteLoudnessScaling),Final)),OutputModulateHow,
- OutputModulationScaling,OutputModulationOrigin,OutputOldValues,
- OutputIndirectionTable,NumberOfOutputModulators));;
- OutputPlace[1] += double2largefixed(ApplyModulation(largefixed2single(
- FastFixedTimes16BitTo24Bit((signed long)(State->RightLoudness
- * State->NoteLoudnessScaling),Final)),OutputModulateHow,
- OutputModulationScaling,OutputModulationOrigin,OutputOldValues,
- OutputIndirectionTable,NumberOfOutputModulators));
- }
- }
- else
- {
- ReturnValue = ((float)Final / MAX16BIT)
- * FastFixed2Float(State->OverallLoudness);
- if (State->Template.IncludeInFinalOutput)
- {
- OutputPlace[0] += double2largefixed(ApplyModulation(largefixed2single(
- FastFixedTimes16BitTo24Bit((signed long)(State->OverallLoudness
- * State->NoteLoudnessScaling),Final)),OutputModulateHow,
- OutputModulationScaling,OutputModulationOrigin,OutputOldValues,
- OutputIndirectionTable,NumberOfOutputModulators));
- }
- }
-
- LongLongAdd(&State->WaveTableSamplePosition,
- &(State->WaveTableSamplePositionDifferential));
- LongLongMaskHighHalf(State->WaveTableSamplePosition,State->FramesPerTable - 1);
-
- return ReturnValue;
- }
-
-
- static void Wave_Mono_8BitIn_NoTime_NoWave(WaveTableStateRec* State,
- long SampleCount, largefixedsigned* RawBuffer)
- {
- LongLongRec LocalWaveTableSamplePosition;
- LongLongRec LocalWaveTableSamplePositionDifferential;
- unsigned long LocalSamplePositionMask;
- signed char* WaveData;
- FastFixedType LocalOverallLoudness;
-
- ERROR((State->WaveTableIndex < 0) || (State->WaveTableIndex
- > Int2FastFixed(State->NumberOfTables - 1)),PRERR(ForceAbort,
- "Wave_Mono_8BitIn_NoTime_NoWave: wave index out of range"));
- LocalOverallLoudness = State->OverallLoudness;
- LocalWaveTableSamplePosition = State->WaveTableSamplePosition;
- LocalWaveTableSamplePositionDifferential = State->WaveTableSamplePositionDifferential;
- LocalSamplePositionMask = State->FramesPerTable - 1;
- PRNGCHK(State->WaveTableMatrix,&(State->WaveTableMatrix[FastFixed2Int(
- State->WaveTableIndex)]),sizeof(State->WaveTableMatrix[FastFixed2Int(
- State->WaveTableIndex)]));
- WaveData = (signed char*)(State->WaveTableMatrix[
- FastFixed2Int(State->WaveTableIndex)]);
-
- while (SampleCount > 0)
- {
- *(RawBuffer++) += FastFixedTimes8BitTo24Bit(LocalOverallLoudness,
- WaveData[LongLongHighHalf(LocalWaveTableSamplePosition)
- & LocalSamplePositionMask]);
- LongLongAdd(&LocalWaveTableSamplePosition,
- &LocalWaveTableSamplePositionDifferential);
- SampleCount -= 1;
- }
-
- State->WaveTableSamplePosition = LocalWaveTableSamplePosition;
- }
-
-
- static void Wave_Stereo_8BitIn_NoTime_NoWave(WaveTableStateRec* State,
- long SampleCount, largefixedsigned* RawBuffer)
- {
- LongLongRec LocalWaveTableSamplePosition;
- LongLongRec LocalWaveTableSamplePositionDifferential;
- unsigned long LocalSamplePositionMask;
- signed char* WaveData;
- FastFixedType LocalLeftLoudness;
- FastFixedType LocalRightLoudness;
-
- ERROR((State->WaveTableIndex < 0) || (State->WaveTableIndex
- > Int2FastFixed(State->NumberOfTables - 1)),PRERR(ForceAbort,
- "Wave_Stereo_8BitIn_NoTime_NoWave: wave index out of range"));
- LocalLeftLoudness = State->LeftLoudness;
- LocalRightLoudness = State->RightLoudness;
- LocalWaveTableSamplePosition = State->WaveTableSamplePosition;
- LocalWaveTableSamplePositionDifferential = State->WaveTableSamplePositionDifferential;
- LocalSamplePositionMask = State->FramesPerTable - 1;
- PRNGCHK(State->WaveTableMatrix,&(State->WaveTableMatrix[FastFixed2Int(
- State->WaveTableIndex)]),sizeof(State->WaveTableMatrix[FastFixed2Int(
- State->WaveTableIndex)]));
- WaveData = (signed char*)(State->WaveTableMatrix[
- FastFixed2Int(State->WaveTableIndex)]);
-
- while (SampleCount > 0)
- {
- signed long SamplePoint;
-
- SamplePoint = WaveData[LongLongHighHalf(LocalWaveTableSamplePosition)
- & LocalSamplePositionMask];
- *(RawBuffer++) += FastFixedTimes8BitTo24Bit(LocalLeftLoudness,SamplePoint);
- *(RawBuffer++) += FastFixedTimes8BitTo24Bit(LocalRightLoudness,SamplePoint);
- LongLongAdd(&LocalWaveTableSamplePosition,
- &LocalWaveTableSamplePositionDifferential);
- SampleCount -= 1;
- }
-
- State->WaveTableSamplePosition = LocalWaveTableSamplePosition;
- }
-
-
- static void Wave_Mono_16BitIn_NoTime_NoWave(WaveTableStateRec* State,
- long SampleCount, largefixedsigned* RawBuffer)
- {
- LongLongRec LocalWaveTableSamplePosition;
- LongLongRec LocalWaveTableSamplePositionDifferential;
- unsigned long LocalSamplePositionMask;
- signed short* WaveData;
- FastFixedType LocalOverallLoudness;
-
- ERROR((State->WaveTableIndex < 0) || (State->WaveTableIndex
- > Int2FastFixed(State->NumberOfTables - 1)),PRERR(ForceAbort,
- "Wave_Mono_16BitIn_NoTime_NoWave: wave index out of range"));
- LocalOverallLoudness = State->OverallLoudness;
- LocalWaveTableSamplePosition = State->WaveTableSamplePosition;
- LocalWaveTableSamplePositionDifferential = State->WaveTableSamplePositionDifferential;
- LocalSamplePositionMask = State->FramesPerTable - 1;
- PRNGCHK(State->WaveTableMatrix,&(State->WaveTableMatrix[FastFixed2Int(
- State->WaveTableIndex)]),sizeof(State->WaveTableMatrix[FastFixed2Int(
- State->WaveTableIndex)]));
- WaveData = (signed short*)(State->WaveTableMatrix[
- FastFixed2Int(State->WaveTableIndex)]);
-
- while (SampleCount > 0)
- {
- *(RawBuffer++) += FastFixedTimes16BitTo24Bit(LocalOverallLoudness,
- WaveData[LongLongHighHalf(LocalWaveTableSamplePosition)
- & LocalSamplePositionMask]);
- LongLongAdd(&LocalWaveTableSamplePosition,
- &LocalWaveTableSamplePositionDifferential);
- SampleCount -= 1;
- }
-
- State->WaveTableSamplePosition = LocalWaveTableSamplePosition;
- }
-
-
- static void Wave_Stereo_16BitIn_NoTime_NoWave(WaveTableStateRec* State,
- long SampleCount, largefixedsigned* RawBuffer)
- {
- LongLongRec LocalWaveTableSamplePosition;
- LongLongRec LocalWaveTableSamplePositionDifferential;
- unsigned long LocalSamplePositionMask;
- signed short* WaveData;
- FastFixedType LocalLeftLoudness;
- FastFixedType LocalRightLoudness;
-
- ERROR((State->WaveTableIndex < 0) || (State->WaveTableIndex
- > Int2FastFixed(State->NumberOfTables - 1)),PRERR(ForceAbort,
- "Wave_Stereo_16BitIn_NoTime_NoWave: wave index out of range"));
- LocalLeftLoudness = State->LeftLoudness;
- LocalRightLoudness = State->RightLoudness;
- LocalWaveTableSamplePosition = State->WaveTableSamplePosition;
- LocalWaveTableSamplePositionDifferential = State->WaveTableSamplePositionDifferential;
- LocalSamplePositionMask = State->FramesPerTable - 1;
- PRNGCHK(State->WaveTableMatrix,&(State->WaveTableMatrix[FastFixed2Int(
- State->WaveTableIndex)]),sizeof(State->WaveTableMatrix[FastFixed2Int(
- State->WaveTableIndex)]));
- WaveData = (signed short*)(State->WaveTableMatrix[
- FastFixed2Int(State->WaveTableIndex)]);
-
- while (SampleCount > 0)
- {
- signed long SamplePoint;
-
- SamplePoint = WaveData[LongLongHighHalf(LocalWaveTableSamplePosition)
- & LocalSamplePositionMask];
- *(RawBuffer++) += FastFixedTimes16BitTo24Bit(LocalLeftLoudness,SamplePoint);
- *(RawBuffer++) += FastFixedTimes16BitTo24Bit(LocalRightLoudness,SamplePoint);
- LongLongAdd(&LocalWaveTableSamplePosition,
- &LocalWaveTableSamplePositionDifferential);
- SampleCount -= 1;
- }
-
- State->WaveTableSamplePosition = LocalWaveTableSamplePosition;
- }
-
-
- static void Wave_Mono_8BitIn_YesTime_NoWave(WaveTableStateRec* State,
- long SampleCount, largefixedsigned* RawBuffer)
- {
- LongLongRec LocalWaveTableSamplePosition;
- LongLongRec LocalWaveTableSamplePositionDifferential;
- unsigned long LocalSamplePositionMask;
- signed char* WaveData;
- FastFixedType LocalOverallLoudness;
-
- ERROR((State->WaveTableIndex < 0) || (State->WaveTableIndex
- > Int2FastFixed(State->NumberOfTables - 1)),PRERR(ForceAbort,
- "Wave_Mono_8BitIn_YesTime_NoWave: wave index out of range"));
- LocalOverallLoudness = State->OverallLoudness;
- LocalWaveTableSamplePosition = State->WaveTableSamplePosition;
- LocalWaveTableSamplePositionDifferential = State->WaveTableSamplePositionDifferential;
- LocalSamplePositionMask = State->FramesPerTable - 1;
- PRNGCHK(State->WaveTableMatrix,&(State->WaveTableMatrix[FastFixed2Int(
- State->WaveTableIndex)]),sizeof(State->WaveTableMatrix[FastFixed2Int(
- State->WaveTableIndex)]));
- WaveData = (signed char*)(State->WaveTableMatrix[
- FastFixed2Int(State->WaveTableIndex)]);
-
- while (SampleCount > 0)
- {
- FastFixedType LeftWeight;
- long ArraySubscript;
- signed long LeftValue;
- signed long RightValue;
-
- /* naive anti-aliasing worked as follows: */
- /* L = left sample, R = right sample, F = fractional portion of index */
- /* S = L(1-F) + RF */
- /* Craig Peeper suggested the following optimization: */
- /* L(1-F)+RF ==> L-LF+RF ==> L+RF-LF ==> L+F(R-L) */
- LeftWeight = LongLongLowHalf(LocalWaveTableSamplePosition)
- >> (32 - FASTFIXEDPRECISION);
- ArraySubscript = LongLongHighHalf(LocalWaveTableSamplePosition)
- & LocalSamplePositionMask;
- /* L+F(R-L) */
- LeftValue = ((signed long)WaveData[ArraySubscript]) << 8; /* convert to 16-bit */
- RightValue = ((signed long)WaveData[ArraySubscript + 1]) << 8; /* to 16-bit */
- *(RawBuffer++) += FastFixedTimes16BitTo24Bit(LocalOverallLoudness,LeftValue
- + ((LeftWeight * (RightValue - LeftValue)) >> 15));
- LongLongAdd(&LocalWaveTableSamplePosition,
- &LocalWaveTableSamplePositionDifferential);
- SampleCount -= 1;
- }
-
- State->WaveTableSamplePosition = LocalWaveTableSamplePosition;
- }
-
-
- static void Wave_Stereo_8BitIn_YesTime_NoWave(WaveTableStateRec* State,
- long SampleCount, largefixedsigned* RawBuffer)
- {
- LongLongRec LocalWaveTableSamplePosition;
- LongLongRec LocalWaveTableSamplePositionDifferential;
- unsigned long LocalSamplePositionMask;
- signed char* WaveData;
- FastFixedType LocalLeftLoudness;
- FastFixedType LocalRightLoudness;
-
- ERROR((State->WaveTableIndex < 0) || (State->WaveTableIndex
- > Int2FastFixed(State->NumberOfTables - 1)),PRERR(ForceAbort,
- "Wave_Stereo_8BitIn_YesTime_NoWave: wave index out of range"));
- LocalLeftLoudness = State->LeftLoudness;
- LocalRightLoudness = State->RightLoudness;
- LocalWaveTableSamplePosition = State->WaveTableSamplePosition;
- LocalWaveTableSamplePositionDifferential = State->WaveTableSamplePositionDifferential;
- LocalSamplePositionMask = State->FramesPerTable - 1;
- PRNGCHK(State->WaveTableMatrix,&(State->WaveTableMatrix[FastFixed2Int(
- State->WaveTableIndex)]),sizeof(State->WaveTableMatrix[FastFixed2Int(
- State->WaveTableIndex)]));
- WaveData = (signed char*)(State->WaveTableMatrix[
- FastFixed2Int(State->WaveTableIndex)]);
-
- while (SampleCount > 0)
- {
- FastFixedType LeftWeight;
- long ArraySubscript;
- signed long LeftValue;
- signed long RightValue;
- signed long CombinedValue;
-
- LeftWeight = LongLongLowHalf(LocalWaveTableSamplePosition)
- >> (32 - FASTFIXEDPRECISION);
- ArraySubscript = LongLongHighHalf(LocalWaveTableSamplePosition)
- & LocalSamplePositionMask;
- /* L+F(R-L) */
- LeftValue = ((signed long)WaveData[ArraySubscript]) << 8; /* convert to 16-bit */
- RightValue = ((signed long)WaveData[ArraySubscript + 1]) << 8; /* to 16-bit */
- CombinedValue = LeftValue + ((LeftWeight * (RightValue - LeftValue)) >> 15);
- /* Oh, Please Mr. Compiler, LeftValue and RightValue are dead now!!! */
- *(RawBuffer++) += FastFixedTimes16BitTo24Bit(LocalLeftLoudness,CombinedValue);
- *(RawBuffer++) += FastFixedTimes16BitTo24Bit(LocalRightLoudness,CombinedValue);
- LongLongAdd(&LocalWaveTableSamplePosition,
- &LocalWaveTableSamplePositionDifferential);
- SampleCount -= 1;
- }
-
- State->WaveTableSamplePosition = LocalWaveTableSamplePosition;
- }
-
-
- static void Wave_Mono_16BitIn_YesTime_NoWave(WaveTableStateRec* State,
- long SampleCount, largefixedsigned* RawBuffer)
- {
- LongLongRec LocalWaveTableSamplePosition;
- LongLongRec LocalWaveTableSamplePositionDifferential;
- unsigned long LocalSamplePositionMask;
- signed short* WaveData;
- FastFixedType LocalOverallLoudness;
-
- ERROR((State->WaveTableIndex < 0) || (State->WaveTableIndex
- > Int2FastFixed(State->NumberOfTables - 1)),PRERR(ForceAbort,
- "Wave_Mono_16BitIn_YesTime_NoWave: wave index out of range"));
- LocalOverallLoudness = State->OverallLoudness;
- LocalWaveTableSamplePosition = State->WaveTableSamplePosition;
- LocalWaveTableSamplePositionDifferential = State->WaveTableSamplePositionDifferential;
- LocalSamplePositionMask = State->FramesPerTable - 1;
- PRNGCHK(State->WaveTableMatrix,&(State->WaveTableMatrix[FastFixed2Int(
- State->WaveTableIndex)]),sizeof(State->WaveTableMatrix[FastFixed2Int(
- State->WaveTableIndex)]));
- WaveData = (signed short*)(State->WaveTableMatrix[
- FastFixed2Int(State->WaveTableIndex)]);
-
- while (SampleCount > 0)
- {
- FastFixedType LeftWeight;
- long ArraySubscript;
- signed long LeftValue;
- signed long RightValue;
-
- LeftWeight = LongLongLowHalf(LocalWaveTableSamplePosition)
- >> (32 - FASTFIXEDPRECISION);
- ArraySubscript = LongLongHighHalf(LocalWaveTableSamplePosition)
- & LocalSamplePositionMask;
- /* L+F(R-L) */
- LeftValue = WaveData[ArraySubscript];
- RightValue = WaveData[ArraySubscript + 1];
- *(RawBuffer++) += FastFixedTimes16BitTo24Bit(LocalOverallLoudness,LeftValue
- + ((LeftWeight * (RightValue - LeftValue)) >> 15));
- LongLongAdd(&LocalWaveTableSamplePosition,
- &LocalWaveTableSamplePositionDifferential);
- SampleCount -= 1;
- }
-
- State->WaveTableSamplePosition = LocalWaveTableSamplePosition;
- }
-
-
- static void Wave_Stereo_16BitIn_YesTime_NoWave(WaveTableStateRec* State,
- long SampleCount, largefixedsigned* RawBuffer)
- {
- LongLongRec LocalWaveTableSamplePosition;
- LongLongRec LocalWaveTableSamplePositionDifferential;
- unsigned long LocalSamplePositionMask;
- signed short* WaveData;
- FastFixedType LocalLeftLoudness;
- FastFixedType LocalRightLoudness;
-
- ERROR((State->WaveTableIndex < 0) || (State->WaveTableIndex
- > Int2FastFixed(State->NumberOfTables - 1)),PRERR(ForceAbort,
- "Wave_Stereo_16BitIn_YesTime_NoWave: wave index out of range"));
- LocalLeftLoudness = State->LeftLoudness;
- LocalRightLoudness = State->RightLoudness;
- LocalWaveTableSamplePosition = State->WaveTableSamplePosition;
- LocalWaveTableSamplePositionDifferential = State->WaveTableSamplePositionDifferential;
- LocalSamplePositionMask = State->FramesPerTable - 1;
- PRNGCHK(State->WaveTableMatrix,&(State->WaveTableMatrix[FastFixed2Int(
- State->WaveTableIndex)]),sizeof(State->WaveTableMatrix[FastFixed2Int(
- State->WaveTableIndex)]));
- WaveData = (signed short*)(State->WaveTableMatrix[
- FastFixed2Int(State->WaveTableIndex)]);
-
- while (SampleCount > 0)
- {
- FastFixedType LeftWeight;
- long ArraySubscript;
- signed long LeftValue;
- signed long RightValue;
- signed long CombinedValue;
-
- LeftWeight = LongLongLowHalf(LocalWaveTableSamplePosition)
- >> (32 - FASTFIXEDPRECISION);
- ArraySubscript = LongLongHighHalf(LocalWaveTableSamplePosition)
- & LocalSamplePositionMask;
- /* L+F(R-L) */
- LeftValue = WaveData[ArraySubscript];
- RightValue = WaveData[ArraySubscript + 1];
- CombinedValue = LeftValue + ((LeftWeight * (RightValue - LeftValue)) >> 15);
- *(RawBuffer++) += FastFixedTimes16BitTo24Bit(LocalLeftLoudness,CombinedValue);
- *(RawBuffer++) += FastFixedTimes16BitTo24Bit(LocalRightLoudness,CombinedValue);
- LongLongAdd(&LocalWaveTableSamplePosition,
- &LocalWaveTableSamplePositionDifferential);
- SampleCount -= 1;
- }
-
- State->WaveTableSamplePosition = LocalWaveTableSamplePosition;
- }
-
-
- static void Wave_Mono_8BitIn_YesTime_YesWave(WaveTableStateRec* State,
- long SampleCount, largefixedsigned* RawBuffer)
- {
- LongLongRec LocalWaveTableSamplePosition;
- LongLongRec LocalWaveTableSamplePositionDifferential;
- unsigned long LocalSamplePositionMask;
- signed char* WaveData0;
- signed char* WaveData1;
- FastFixedType Wave0Weight;
- FastFixedType LocalOverallLoudness;
-
- ERROR((State->WaveTableIndex < 0) || (State->WaveTableIndex
- > Int2FastFixed(State->NumberOfTables - 1)),PRERR(ForceAbort,
- "Wave_Mono_8BitIn_YesTime_YesWave: wave index out of range"));
- if (FastFixed2Int(State->WaveTableIndex) == State->NumberOfTables - 1)
- {
- /* this is done in case the wave table index is at the maximum, in which */
- /* case there is no table+1 to interpolate with. */
- Wave_Mono_8BitIn_YesTime_NoWave(State,SampleCount,RawBuffer);
- return;
- }
- LocalOverallLoudness = State->OverallLoudness;
- LocalWaveTableSamplePosition = State->WaveTableSamplePosition;
- LocalWaveTableSamplePositionDifferential = State->WaveTableSamplePositionDifferential;
- LocalSamplePositionMask = State->FramesPerTable - 1;
- PRNGCHK(State->WaveTableMatrix,&(State->WaveTableMatrix[FastFixed2Int(
- State->WaveTableIndex)]),sizeof(State->WaveTableMatrix[FastFixed2Int(
- State->WaveTableIndex)]));
- WaveData0 = (signed char*)(State->WaveTableMatrix[
- FastFixed2Int(State->WaveTableIndex)]);
- PRNGCHK(State->WaveTableMatrix,&(State->WaveTableMatrix[FastFixed2Int(
- State->WaveTableIndex) + 1]),sizeof(State->WaveTableMatrix[FastFixed2Int(
- State->WaveTableIndex) + 1]));
- WaveData1 = (signed char*)(State->WaveTableMatrix[
- FastFixed2Int(State->WaveTableIndex) + 1]);
- Wave0Weight = State->WaveTableIndex & FASTFIXEDFRACTMASK;
-
- while (SampleCount > 0)
- {
- FastFixedType LeftWeight;
- long ArraySubscript;
- signed long Left0Value;
- signed long Right0Value;
- signed long Left1Value;
- signed long Right1Value;
- FastFixedType Wave0Temp;
-
- LeftWeight = LongLongLowHalf(LocalWaveTableSamplePosition)
- >> (32 - FASTFIXEDPRECISION);
- ArraySubscript = LongLongHighHalf(LocalWaveTableSamplePosition)
- & LocalSamplePositionMask;
- /* L+F(R-L) -- applied twice */
- Left0Value = ((signed long)WaveData0[ArraySubscript]) << 8; /* convert to 16-bit */
- Right0Value = ((signed long)WaveData0[ArraySubscript + 1]) << 8; /* to 16-bit */
- Left1Value = ((signed long)WaveData1[ArraySubscript]) << 8; /* convert to 16-bit */
- Right1Value = ((signed long)WaveData1[ArraySubscript + 1]) << 8; /* to 16-bit */
- Wave0Temp = Left0Value + ((LeftWeight * (Right0Value - Left0Value)) >> 15);
- *(RawBuffer++) += FastFixedTimes16BitTo24Bit(LocalOverallLoudness,
- Wave0Temp + ((Wave0Weight * (Left1Value + ((LeftWeight * (Right1Value
- - Left1Value)) >> 15) - Wave0Temp)) >> 15));
- LongLongAdd(&LocalWaveTableSamplePosition,
- &LocalWaveTableSamplePositionDifferential);
- SampleCount -= 1;
- }
-
- State->WaveTableSamplePosition = LocalWaveTableSamplePosition;
- }
-
-
- static void Wave_Stereo_8BitIn_YesTime_YesWave(WaveTableStateRec* State,
- long SampleCount, largefixedsigned* RawBuffer)
- {
- LongLongRec LocalWaveTableSamplePosition;
- LongLongRec LocalWaveTableSamplePositionDifferential;
- unsigned long LocalSamplePositionMask;
- signed char* WaveData0;
- signed char* WaveData1;
- FastFixedType Wave0Weight;
- FastFixedType LocalLeftLoudness;
- FastFixedType LocalRightLoudness;
-
- ERROR((State->WaveTableIndex < 0) || (State->WaveTableIndex
- > Int2FastFixed(State->NumberOfTables - 1)),PRERR(ForceAbort,
- "Wave_Stereo_8BitIn_YesTime_YesWave: wave index out of range"));
- if (FastFixed2Int(State->WaveTableIndex) == State->NumberOfTables - 1)
- {
- /* this is done in case the wave table index is at the maximum, in which */
- /* case there is no table+1 to interpolate with. */
- Wave_Stereo_8BitIn_YesTime_NoWave(State,SampleCount,RawBuffer);
- return;
- }
- LocalLeftLoudness = State->LeftLoudness;
- LocalRightLoudness = State->RightLoudness;
- LocalWaveTableSamplePosition = State->WaveTableSamplePosition;
- LocalWaveTableSamplePositionDifferential = State->WaveTableSamplePositionDifferential;
- LocalSamplePositionMask = State->FramesPerTable - 1;
- PRNGCHK(State->WaveTableMatrix,&(State->WaveTableMatrix[FastFixed2Int(
- State->WaveTableIndex)]),sizeof(State->WaveTableMatrix[FastFixed2Int(
- State->WaveTableIndex)]));
- WaveData0 = (signed char*)(State->WaveTableMatrix[
- FastFixed2Int(State->WaveTableIndex)]);
- PRNGCHK(State->WaveTableMatrix,&(State->WaveTableMatrix[FastFixed2Int(
- State->WaveTableIndex) + 1]),sizeof(State->WaveTableMatrix[FastFixed2Int(
- State->WaveTableIndex) + 1]));
- WaveData1 = (signed char*)(State->WaveTableMatrix[
- FastFixed2Int(State->WaveTableIndex) + 1]);
- Wave0Weight = State->WaveTableIndex & FASTFIXEDFRACTMASK;
-
- while (SampleCount > 0)
- {
- FastFixedType LeftWeight;
- long ArraySubscript;
- signed long Left0Value;
- signed long Right0Value;
- signed long Left1Value;
- signed long Right1Value;
- FastFixedType Wave0Temp;
-
- LeftWeight = LongLongLowHalf(LocalWaveTableSamplePosition)
- >> (32 - FASTFIXEDPRECISION);
- ArraySubscript = LongLongHighHalf(LocalWaveTableSamplePosition)
- & LocalSamplePositionMask;
- /* L+F(R-L) -- applied twice */
- Left0Value = ((signed long)WaveData0[ArraySubscript]) << 8; /* convert to 16-bit */
- Right0Value = ((signed long)WaveData0[ArraySubscript + 1]) << 8; /* to 16-bit */
- Left1Value = ((signed long)WaveData1[ArraySubscript]) << 8; /* convert to 16-bit */
- Right1Value = ((signed long)WaveData1[ArraySubscript + 1]) << 8; /* to 16-bit */
- Wave0Temp = Left0Value + ((LeftWeight * (Right0Value - Left0Value)) >> 15);
- Wave0Temp = Wave0Temp + ((Wave0Weight * (Left1Value + ((LeftWeight * (Right1Value
- - Left1Value)) >> 15) - Wave0Temp)) >> 15);
- *(RawBuffer++) += FastFixedTimes16BitTo24Bit(LocalLeftLoudness,Wave0Temp);
- *(RawBuffer++) += FastFixedTimes16BitTo24Bit(LocalRightLoudness,Wave0Temp);
- LongLongAdd(&LocalWaveTableSamplePosition,
- &LocalWaveTableSamplePositionDifferential);
- SampleCount -= 1;
- }
-
- State->WaveTableSamplePosition = LocalWaveTableSamplePosition;
- }
-
-
- static void Wave_Mono_16BitIn_YesTime_YesWave(WaveTableStateRec* State,
- long SampleCount, largefixedsigned* RawBuffer)
- {
- LongLongRec LocalWaveTableSamplePosition;
- LongLongRec LocalWaveTableSamplePositionDifferential;
- unsigned long LocalSamplePositionMask;
- signed short* WaveData0;
- signed short* WaveData1;
- FastFixedType Wave0Weight;
- FastFixedType LocalOverallLoudness;
-
- ERROR((State->WaveTableIndex < 0) || (State->WaveTableIndex
- > Int2FastFixed(State->NumberOfTables - 1)),PRERR(ForceAbort,
- "Wave_Mono_16BitIn_YesTime_YesWave: wave index out of range"));
- if (FastFixed2Int(State->WaveTableIndex) == State->NumberOfTables - 1)
- {
- /* this is done in case the wave table index is at the maximum, in which */
- /* case there is no table+1 to interpolate with. */
- Wave_Mono_16BitIn_YesTime_NoWave(State,SampleCount,RawBuffer);
- return;
- }
- LocalOverallLoudness = State->OverallLoudness;
- LocalWaveTableSamplePosition = State->WaveTableSamplePosition;
- LocalWaveTableSamplePositionDifferential = State->WaveTableSamplePositionDifferential;
- LocalSamplePositionMask = State->FramesPerTable - 1;
- PRNGCHK(State->WaveTableMatrix,&(State->WaveTableMatrix[FastFixed2Int(
- State->WaveTableIndex)]),sizeof(State->WaveTableMatrix[FastFixed2Int(
- State->WaveTableIndex)]));
- WaveData0 = (signed short*)(State->WaveTableMatrix[
- FastFixed2Int(State->WaveTableIndex)]);
- PRNGCHK(State->WaveTableMatrix,&(State->WaveTableMatrix[FastFixed2Int(
- State->WaveTableIndex) + 1]),sizeof(State->WaveTableMatrix[FastFixed2Int(
- State->WaveTableIndex) + 1]));
- WaveData1 = (signed short*)(State->WaveTableMatrix[
- FastFixed2Int(State->WaveTableIndex) + 1]);
- Wave0Weight = State->WaveTableIndex & FASTFIXEDFRACTMASK;
-
- while (SampleCount > 0)
- {
- FastFixedType LeftWeight;
- long ArraySubscript;
- signed long Left0Value;
- signed long Right0Value;
- signed long Left1Value;
- signed long Right1Value;
- FastFixedType Wave0Temp;
-
- LeftWeight = LongLongLowHalf(LocalWaveTableSamplePosition)
- >> (32 - FASTFIXEDPRECISION);
- ArraySubscript = LongLongHighHalf(LocalWaveTableSamplePosition)
- & LocalSamplePositionMask;
- /* L+F(R-L) -- applied twice */
- Left0Value = WaveData0[ArraySubscript];
- Right0Value = WaveData0[ArraySubscript + 1];
- Left1Value = WaveData1[ArraySubscript];
- Right1Value = WaveData1[ArraySubscript + 1];
- Wave0Temp = Left0Value + ((LeftWeight * (Right0Value - Left0Value)) >> 15);
- *(RawBuffer++) += FastFixedTimes16BitTo24Bit(LocalOverallLoudness,
- Wave0Temp + ((Wave0Weight * (Left1Value + ((LeftWeight * (Right1Value
- - Left1Value)) >> 15) - Wave0Temp)) >> 15));
- LongLongAdd(&LocalWaveTableSamplePosition,
- &LocalWaveTableSamplePositionDifferential);
- SampleCount -= 1;
- }
-
- State->WaveTableSamplePosition = LocalWaveTableSamplePosition;
- }
-
-
- static void Wave_Stereo_16BitIn_YesTime_YesWave(WaveTableStateRec* State,
- long SampleCount, largefixedsigned* RawBuffer)
- {
- LongLongRec LocalWaveTableSamplePosition;
- LongLongRec LocalWaveTableSamplePositionDifferential;
- unsigned long LocalSamplePositionMask;
- signed short* WaveData0;
- signed short* WaveData1;
- FastFixedType Wave0Weight;
- FastFixedType LocalLeftLoudness;
- FastFixedType LocalRightLoudness;
-
- ERROR((State->WaveTableIndex < 0) || (State->WaveTableIndex
- > Int2FastFixed(State->NumberOfTables - 1)),PRERR(ForceAbort,
- "Wave_Stereo_16BitIn_YesTime_YesWave: wave index out of range"));
- if (FastFixed2Int(State->WaveTableIndex) == State->NumberOfTables - 1)
- {
- /* this is done in case the wave table index is at the maximum, in which */
- /* case there is no table+1 to interpolate with. */
- Wave_Stereo_16BitIn_YesTime_NoWave(State,SampleCount,RawBuffer);
- return;
- }
- LocalLeftLoudness = State->LeftLoudness;
- LocalRightLoudness = State->RightLoudness;
- LocalWaveTableSamplePosition = State->WaveTableSamplePosition;
- LocalWaveTableSamplePositionDifferential = State->WaveTableSamplePositionDifferential;
- LocalSamplePositionMask = State->FramesPerTable - 1;
- PRNGCHK(State->WaveTableMatrix,&(State->WaveTableMatrix[FastFixed2Int(
- State->WaveTableIndex)]),sizeof(State->WaveTableMatrix[FastFixed2Int(
- State->WaveTableIndex)]));
- WaveData0 = (signed short*)(State->WaveTableMatrix[
- FastFixed2Int(State->WaveTableIndex)]);
- PRNGCHK(State->WaveTableMatrix,&(State->WaveTableMatrix[FastFixed2Int(
- State->WaveTableIndex) + 1]),sizeof(State->WaveTableMatrix[FastFixed2Int(
- State->WaveTableIndex) + 1]));
- WaveData1 = (signed short*)(State->WaveTableMatrix[
- FastFixed2Int(State->WaveTableIndex) + 1]);
- Wave0Weight = State->WaveTableIndex & FASTFIXEDFRACTMASK;
-
- while (SampleCount > 0)
- {
- FastFixedType LeftWeight;
- long ArraySubscript;
- signed long Left0Value;
- signed long Right0Value;
- signed long Left1Value;
- signed long Right1Value;
- FastFixedType Wave0Temp;
-
- LeftWeight = LongLongLowHalf(LocalWaveTableSamplePosition)
- >> (32 - FASTFIXEDPRECISION);
- ArraySubscript = LongLongHighHalf(LocalWaveTableSamplePosition)
- & LocalSamplePositionMask;
- /* L+F(R-L) -- applied twice */
- Left0Value = WaveData0[ArraySubscript];
- Right0Value = WaveData0[ArraySubscript + 1];
- Left1Value = WaveData1[ArraySubscript];
- Right1Value = WaveData1[ArraySubscript + 1];
- Wave0Temp = Left0Value + ((LeftWeight * (Right0Value - Left0Value)) >> 15);
- Wave0Temp = Wave0Temp + ((Wave0Weight * (Left1Value + ((LeftWeight
- * (Right1Value - Left1Value)) >> 15) - Wave0Temp)) >> 15);
- *(RawBuffer++) += FastFixedTimes16BitTo24Bit(LocalLeftLoudness,Wave0Temp);
- *(RawBuffer++) += FastFixedTimes16BitTo24Bit(LocalRightLoudness,Wave0Temp);
- LongLongAdd(&LocalWaveTableSamplePosition,
- &LocalWaveTableSamplePositionDifferential);
- SampleCount -= 1;
- }
-
- State->WaveTableSamplePosition = LocalWaveTableSamplePosition;
- }
-
-
- static void Wave_NoOutput(WaveTableStateRec* State,
- long SampleCount, largefixedsigned* RawBuffer)
- {
- }
-